package com.heima.news.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.news.config.RabbitMQConfig;
import com.heima.news.domain.News;

import com.heima.news.domain.NewsNotice;
import com.heima.news.mapper.NewsMapper;
import com.heima.news.mapper.NewsNoticeMapper;
import com.heima.news.mq.send.NewsMessageSender;
import com.heima.news.service.NewsService;

import com.heima.news.utils.SensitiveWordUtil;
import com.ruoyi.common.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class NewsServiceImpl extends ServiceImpl<NewsMapper, News> implements NewsService {
    @Autowired
    private NewsMapper newsMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private NewsMessageSender newsMessageSender;

    @Autowired
    private NewsNoticeMapper newsNoticeMapper;


    @Override
    public List<News> listNews(News news) {
        //使用 mybatis plus
        //将搜索值字符串数组转为数字
        List<Integer> typeIds = null;
        if (news.getSearchValue() != null) {
            String[] searchValues = news.getSearchValue().split(",");
            typeIds = Arrays.stream(searchValues).map(Integer::parseInt).collect(Collectors.toList());
        }
        List<News> newsList = lambdaQuery().
                //判断状态值不为空
                        eq(news.getStatus() != null,News::getStatus,news.getStatus())
                //eq(news.getTypeId() != null,News::getTypeId,news.getTypeId()).
                .in(typeIds != null,News::getTypeId, typeIds)
                .like(news.getTitle() != null,News::getTitle,news.getTitle()).
                like(news.getSource() != null,News::getSource,news.getSource())
                .list();
        return newsList;
    }



    //新增新闻
    @Override
    @CacheEvict(cacheNames = "tbNews", allEntries = true)
    public int insertTbNews(News tbNews) {
        tbNews.setCreateBy(SecurityUtils.getUsername());
        tbNews.setCreateTime(new Date());
        int insert = newsMapper.insert(tbNews);


        return insert;
    }

    /**
     * 修改新闻管理
     *
     * @param tbNews 新闻管理
     * @return 结果
     */
    @Override
    @CacheEvict(cacheNames = "tbNews", allEntries = true)
    public int updateTbNews(News tbNews)
    {
        tbNews.setUpdateBy(SecurityUtils.getUsername());
        tbNews.setUpdateTime(new Date());
        int i = baseMapper.updateById(tbNews);

        if (i > 0) {
            newsMessageSender.sendNewsUpdateMessage(tbNews);
        }
        return i;
    }

    @Override
    public int deleteTbNewsByNewsIds(Long[] newsIds) {
        try {
            for (Long newsId : newsIds) {
                News news = baseMapper.selectById(newsId);
                news.setUpdateBy(SecurityUtils.getUsername());
                news.setUpdateTime(new Date());
                news.setStatus("4");
                baseMapper.updateById(news);
                newsMessageSender.sendNewsDeleteMessage(news);
            }
            return 1;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @Transactional
    @Override
    public Boolean delayPublishNews(List<Integer> newsIds) {
        List<News> newsList = lambdaQuery()
                .eq(News::getStatus, 1)
                .in(News::getNewsId, newsIds)
                .list();

        if (newsList == null || newsList.isEmpty()) {
            throw new IllegalArgumentException("没有找到符合条件的新闻进行发布！");
        }

        for (News news1 : newsList) {
            if (SensitiveWordUtil.containsSensitiveWord(news1.getTitle())) {
                throw new IllegalArgumentException("发布失败，ID:" + news1.getNewsId() + " 的新闻标题包含敏感词");
            }
        }

        try {
            for (News news : newsList) {
                if (news.getDelayTime() != null && news.getDelayTime() > 0) {
                    // 设置为延迟发布中
                    news.setStatus("2");
                    news.setUpdateTime(new Date());
                    // 立即更新状态
                    updateById(news);

                    // 转换为秒
                    int delaySeconds = news.getDelayTime() * 60;
                    sendDelayNews(news.getNewsId().longValue(), delaySeconds);

                    log.info("【发送延迟发布】新闻ID={}，延迟={}分钟", news.getNewsId(), news.getDelayTime());
                } else {
                    // 设置为立即发布
                    newsMessageSender.sendNewsInsertMessage(news);
                    news.setStatus("3");
                    news.setUpdateTime(new Date());
                    // 立即更新状态
                    updateById(news);

                    log.info("【立即发布】新闻ID={}", news.getNewsId());
                }
            }
            return true;
        } catch (Exception e) {
            log.error("【发布异常】新闻批量发布异常：{}", e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    @Transactional
    @Override
    public void publishNewsById(Long newsId) {
        News news = newsMapper.selectById(newsId);
        // 2 = 延迟发布中
        if (news != null && "2".equals(news.getStatus())) {
            // 3 = 已发布
            newsMessageSender.sendNewsInsertMessage(news);
            news.setStatus("3");
            news.setUpdateTime(new Date());
            newsMapper.updateById(news);
        }
    }

    /**
     * 删除旧新闻
     */
    @Override
    public void deleteOldNews() {
        QueryWrapper<News> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 4)
                .lt("update_time", LocalDateTime.now().minusDays(7));
        newsMapper.delete(queryWrapper);
    }


    @Override
    public void updateByNoticeId(News tbNews) {

        newsMapper.updateByNoticeId(tbNews);
    }

    @Override
    public int removeByNoticeIds(Long[] noticeIds) {
        try {
            for (Long noticeId : noticeIds) {
                newsMapper.removeByNoticeIds(noticeId);
            }
            return 1;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public void sendDelayNews(Long newsId, int delaySeconds) {
        rabbitTemplate.convertAndSend(
                RabbitMQConfig.DELAY_EXCHANGE,
                RabbitMQConfig.DELAY_ROUTING_KEY,
                // 消息内容，发送新闻ID
                newsId,
                message -> {
                    message.getMessageProperties().setDelay(delaySeconds * 1000); // 设置延迟毫秒
                    return message;
                });
    }

}
